home *** CD-ROM | disk | FTP | other *** search
/ NeXTSTEP 3.3 (Developer)…68k, x86, SPARC, PA-RISC] / NeXTSTEP 3.3 Dev Intel.iso / NextDeveloper / Headers / foundation / NSException.h < prev    next >
Text File  |  1994-05-13  |  9KB  |  230 lines

  1. /*    NSException.h
  2.       Copyright 1994, NeXT, Inc.
  3.     NeXT, April 1994
  4. */
  5.  
  6. #import <foundation/NSDictionary.h>
  7. #include <setjmp.h>
  8.  
  9. /***************    Exception names        ***************/
  10.  
  11. extern NSString *NSGenericException;
  12. extern NSString *NSRangeException;
  13. extern NSString *NSInvalidArgumentException;
  14. extern NSString *NSParseErrorException;
  15. extern NSString *NSInternalInconsistencyException;
  16. extern NSString *NSObjCInadequateRuntimeInformation;
  17.  
  18. extern NSString *NSCodingException;
  19. extern NSString *NSObjectInaccessibleException;
  20. extern NSString *NSObjectNotAvailableException;
  21. extern NSString *NSDestinationInvalidException;
  22. extern NSString *NSOwnershipTransferException;
  23.     
  24. extern NSString *NSPortTimoutException;
  25. extern NSString *NSInvalidSendPort;
  26. extern NSString *NSInvalidReceivePort;
  27. extern NSString *NSPortSendError;
  28. extern NSString *NSPortReceiveError;
  29. extern NSString *NSPortNameRegistrationError;
  30.  
  31. extern NSString *NSArchiverArchiveInconsistency;
  32. extern NSString *NSArchiverClassError;
  33. extern NSString *NSArchiverDescriptorError;
  34. extern NSString *NSArchiverWriteReferenceError;
  35.  
  36. extern NSString *NSDateMissingTimeZone;
  37.  
  38. /***************    Exception object    ***************/
  39.  
  40. @interface NSException:NSObject <NSCopying> {
  41.     /* Exceptions are immutable, although they may retain objects in a dictionary that may be mutable;
  42.     Note that -description is used when an exception is reported and can be redefined */
  43.     NSString        *name;        /* Exception name */
  44.     NSString        *reason;     /* Human readable reason for raising */
  45.     NSDictionary    *userInfo;    /* Any arbitrary other data */
  46. }
  47.  
  48. + (NSException *)exceptionWithName:(NSString *)name reason:(NSString *)reason userInfo:(NSDictionary *)userInfo;
  49.     /* Creates an autoreleased exception */
  50.  
  51. - (NSString *)exceptionName;
  52.  
  53. - (NSString *)exceptionReason;
  54.  
  55. - (NSDictionary *)exceptionUserInfo;
  56.     /* May return nil */
  57.  
  58. - (volatile void)raise;
  59.     /* Dispatches according to the appropriate catcher;
  60.     Never returns */
  61.  
  62. - initWithName:(NSString *)name reason:(NSString *)reason userInfo:(NSDictionary *)userInfo;
  63.     /* Designated initializer */
  64.  
  65. @end
  66.  
  67. /***************    Conveniences for raising    ***************/
  68.  
  69. @interface NSException (NSExceptionRaisingConveniences)
  70.  
  71. + (volatile void)raise:(NSString *)name format:(NSString *)format, ...;
  72.     /* Create an exception then raise it; 
  73.     format is used to create the exception 'reason' */
  74.  
  75. + (volatile void)raise:(NSString *)name format:(NSString *)format arguments:(va_list)argList;
  76.  
  77. @end
  78.  
  79. /***************    Raising and catching    ***************/
  80.  
  81. #define NSExceptionBase 100000 // TEMPORARY!
  82. #define NSLastException 100999 // TEMPORARY!
  83.  
  84. // Private definition
  85. typedef struct _NSHandler {    /* a node in the handler chain */
  86.     jmp_buf        jumpState;    /* place to longjmp to */
  87.     struct _NSHandler    *next;        /* ptr to next handler */
  88.     int         code;        /* error code of exception; always >=NSExceptionBase and <=NSLastException for now */
  89.     const void        *data1;        /* The exception object */
  90.     const void        *data2;        /* Reserved for compatibility */
  91. } NSHandler;
  92.  
  93. /* NS_DURING, NS_HANDLER and NS_ENDHANDLER are always used like:
  94.  
  95.     NS_DURING
  96.         some code which might raise an error
  97.     NS_HANDLER
  98.         code that will be jumped to if an error occurs
  99.     NS_ENDHANDLER
  100.  
  101.    If any error is raised within the first block of code, the second block of code will be jumped to.  Typically, this code will clean up any resources allocated in the routine, possibly case on the error code and perform special processing, and default to -raise again the exception to the next handler.  Within the scope of the handler, a local variable called 'exception' holds the raised exception.
  102.    It is illegal to exit the first block of code by any other means than
  103.    NS_VALRETURN, NS_VOIDRETURN, or just falling out the bottom.
  104.  */
  105.  
  106. /* private support routines.  Do not call directly. */
  107. extern void _NSAddHandler(NSHandler *handler);
  108. extern void _NSRemoveHandler(NSHandler *handler);
  109. extern _setjmp(jmp_buf env);
  110.  
  111. #define NS_DURING { NSHandler _localHandler;            \
  112.             _NSAddHandler(&_localHandler);        \
  113.             if( !_setjmp(_localHandler.jumpState) ) {
  114.  
  115. #define NS_HANDLER _NSRemoveHandler(&_localHandler); } else { \
  116.             NSException    *exception = (_localHandler.code >= NSExceptionBase && _localHandler.code <= NSLastException) ? (id)_localHandler.data1 : nil;
  117.  
  118. #define NS_ENDHANDLER exception = nil; /* to avoid compiler warning */}}
  119.  
  120. #define NS_VALRETURN(val)  do { typeof(val) temp = (val);    \
  121.             _NSRemoveHandler(&_localHandler);    \
  122.             return(temp); } while (0)
  123.  
  124. #define NS_VOIDRETURN    do { _NSRemoveHandler(&_localHandler);    \
  125.             return; } while (0)
  126.  
  127. /***************    Changing the top level error catcher    ***********/
  128.  
  129. /* The top level error catcher can be set to look for certain exceptions, do some work, and then either abort or call the previous top level error catcher */
  130.  
  131. typedef volatile void NSUncaughtExceptionHandler(NSException *exception);
  132.  
  133. extern NSUncaughtExceptionHandler *NSGetUncaughtExceptionHandler(void);
  134. extern void NSSetUncaughtExceptionHandler(NSUncaughtExceptionHandler *);
  135.  
  136. /***********    Assertion of program consistency        ***********/
  137.  
  138. /* Assertions evaluate a condition, and if it is false, they call the NSAssertionHandler for the current thread to report that fact.  The assertion macros also take a "description" argument, which should describe the failure that is being tested for.  The description is a printf-style format NSString.  N args may be passed using the NSAssertN() variations.  When calling from within a method, the object's class and method name need not be included in the description, since those args are passed separately.
  139.  
  140. Assertions are compiled into code if the cpp macro NS_BLOCK_ASSERTIONS is defined.  Runtime control is achieved by substituting a different assertion handler.
  141.  
  142. Since these macros pass the variables "self" and "_cmd" automatically, they assume that they are being called from within a method context. There is a parallel set of macros for use within C functions. 
  143. */
  144.  
  145.  
  146. @class NSAssertionHandler;
  147.  
  148. /* Implementation of asserts (ignore) */
  149. #ifdef NS_BLOCK_ASSERTIONS
  150. #define _NSAssertBody(condition, desc, arg1, arg2, arg3)    \
  151.     do {                        \
  152.     if (!(condition)) {                \
  153.         [[NSAssertionHandler currentHandler] handleFailureInMethod:_cmd object:self file:[NSString stringWithCString:__FILE__] lineNumber:__LINE__ description:(desc), (arg1), (arg2), (arg3)];    \
  154.     }                        \
  155.     } while(0)
  156. #define _NSCAssertBody(condition, desc, arg1, arg2, arg3)    \
  157.     do {                        \
  158.     if (!(condition)) {                \
  159.         [[NSAssertionHandler currentHandler] handleFailureInFunction:[NSString stringWithCString:__PRETTY_FUNCTION__] file:[NSString stringWithCString:__FILE__] lineNumber:__LINE__ description:(desc), (arg1), (arg2), (arg3)];    \
  160.     }                        \
  161.     } while(0)
  162. #else
  163. #define _NSAssertBody(condition, desc, arg1, arg2, arg3)
  164. #define _NSCAssertBody(condition, desc, arg1, arg2, arg3)
  165. #endif
  166.  
  167.  
  168. /*
  169.  * Asserts to use in Objective-C method bodies
  170.  */
  171.  
  172. #define NSAssert5(condition, desc, arg1, arg2, arg3, arg4, arg5)    \
  173.     _NSAssertBody((condition), (desc), (arg1), (arg2), (arg3), (arg4), (arg5))
  174.  
  175. #define NSAssert4(condition, desc, arg1, arg2, arg3, arg4)    \
  176.     _NSAssertBody((condition), (desc), (arg1), (arg2), (arg3), (arg4))
  177.  
  178. #define NSAssert3(condition, desc, arg1, arg2, arg3)    \
  179.     _NSAssertBody((condition), (desc), (arg1), (arg2), (arg3))
  180.  
  181. #define NSAssert2(condition, desc, arg1, arg2)        \
  182.     _NSAssertBody((condition), (desc), (arg1), (arg2), 0)
  183.  
  184. #define NSAssert1(condition, desc, arg1)        \
  185.     _NSAssertBody((condition), (desc), (arg1), 0, 0)
  186.  
  187. #define NSAssert(condition, desc)            \
  188.     _NSAssertBody((condition), (desc), 0, 0, 0)
  189.  
  190. /* convenience for validating parameters.  The text of the condition that fails is passed to the handler. */
  191. #define NSParameterAssert(condition)            \
  192.     _NSAssertBody((condition), @"Invalid parameter not satisfying: %s", #condition, 0, 0)
  193.  
  194. /*
  195.  * Asserts to use in C function bodies
  196.  */
  197.  
  198. #define NSCAssert5(condition, desc, arg1, arg2, arg3, arg4, arg5)    \
  199.     _NSCAssertBody((condition), (desc), (arg1), (arg2), (arg3), (arg4), (arg5))
  200.  
  201. #define NSCAssert4(condition, desc, arg1, arg2, arg3, arg4)    \
  202.     _NSCAssertBody((condition), (desc), (arg1), (arg2), (arg3), (arg4))
  203.  
  204. #define NSCAssert3(condition, desc, arg1, arg2, arg3)    \
  205.     _NSCAssertBody((condition), (desc), (arg1), (arg2), arg3)
  206.  
  207. #define NSCAssert2(condition, desc, arg1, arg2)    \
  208.     _NSCAssertBody((condition), (desc), (arg1), (arg2), 0)
  209.  
  210. #define NSCAssert1(condition, desc, arg1)        \
  211.     _NSCAssertBody((condition), (desc), (arg1), 0, 0)
  212.  
  213. #define NSCAssert(condition, desc)            \
  214.     _NSCAssertBody((condition), (desc), 0, 0, 0)
  215.  
  216. /* convenience for validating parameters.  The text of the condition that fails is passed to the handler. */
  217. #define NSCParameterAssert(condition)            \
  218.     _NSCAssertBody((condition), @"Invalid parameter not satisfying: %s", #condition, 0, 0)
  219.  
  220.  
  221. @interface NSAssertionHandler : NSObject
  222.  
  223. + (NSAssertionHandler *)currentHandler;
  224.  
  225. - (void)handleFailureInMethod:(SEL)selector object:object file:(NSString *)fileName lineNumber:(int)line description:(NSString *)format,...;
  226.  
  227. - (void)handleFailureInFunction:(NSString *)functionName file:(NSString *)fileName lineNumber:(int)line description:(NSString *)format,...;
  228.  
  229. @end
  230.